注意:所有文章除特别说明外,转载请注明出处.
第六章 单例模式与多线程
[TOC]
6.1 立即加载/“饿汉模式”
立即加载,在使用类的时候已经将对象创建完毕,常见的实现是直接new实例化。
6.2 延迟加载/“懒汉模式”
延迟加载就是在调用get()方法时实例才被创建,常见的方法是在get()方法中进行new实例化。
6.2.2 延迟加载/“懒汉模式的缺点”
在多线程环境下创建的是多个对象,不是单例模式。
解决方案
1. 生命synchronized关键字
缺点:此种方法运行效率低,下一个线程想要取得对象需要等待上一个线程释放锁才行。
2. 同步代码块
缺点:和synchronized方法一样,效率低
3. 针对某些重要的程序进行单独的同步
4. DCL双检查锁机制
首先加入锁机制,然后再次判断对象是否存在
6.3 静态内置类实现单例模式
DCL可以解决多线程单例模式的非线程安全问题。但静态内置类也可以达到同样效果。
private static class handler {
private static MyObject hd = new MyObject();
}
//构造方法
public static MyObject getInstance(){
return handler.hd;
}
6.4 序列化与反序列化的单例模式
静态内置类可以达到线程安全问题,但如果遇到序列化对象时,使用默认的方式运行得到的结果还是多例的。
解决方法
在反序列化中使用 readResolve() 方法
6.5 static块实现单例模式
因为静态块在使用类的时候就已经执行了,所以可以利用这一特性实现单例模式。
private static MyObject instance = null;
static {
instance = new MyObject();
}
public static MyObject getInstance(){
return instance;
}
6.6 枚举类enum实现单例模式
在使用枚举类时构造方法会被自动调用,可以利用这一特性实现单例模式。